import { FarrisDesignBaseNestedComponent } from '@farris/designer-element';
import { ComponentResolveContext, DesignerEnvType, DomService, FormBasicService, FormComponentType } from '@farris/designer-services';
import { BuilderHTMLElement } from '@farris/designer-element';
import { DgControl } from '../../../../utils/dg-control';
import { FormPropertyChangeObject } from '../../../../entity/property-change-entity';

export default class FdContainerBaseComponent extends FarrisDesignBaseNestedComponent {
    envType: DesignerEnvType;

    constructor(component: any, options: any) {
        super(component, options);

        // 组件所属分类为“容器”
        this.category = 'container';
        const serviceHost = this.options.designerHost;
        const formBasicService = serviceHost.getService('FormBasicService') as FormBasicService;
        if (formBasicService) {
            this.envType = formBasicService.envType;
        }
    }

    /**
     * 属性变更后事件：默认监听样式类属性变更，并触发模板重绘
     * @param changeObject 变更集
     * @param propertyIDs 需要额外监听的属性ID列表
     */
    onPropertyChanged(changeObject: FormPropertyChangeObject, propertyIDs?: string[]): void {
        let dynamicPropertyIDs = ['appearance.class', 'appearance.style', 'size.width', 'size.height', 'inlineStyle'];
        if (propertyIDs) {
            dynamicPropertyIDs = dynamicPropertyIDs.concat(propertyIDs);
        }

        const propertyPath = changeObject.propertyPath ? changeObject.propertyPath + '.' : '';
        if (dynamicPropertyIDs.includes(propertyPath + changeObject.propertyID)) {
            this.triggerRedraw();
        }

    }
    /**
     * 判断是否可以接收拖拽新增的子级控件，容器类通用的条件
     * @param data 新控件的类型、所属分类
     * @returns boolean
     */
    canAccepts(sourceElement: BuilderHTMLElement, targetElement: BuilderHTMLElement): boolean {

        const result = this.canAccept(sourceElement, targetElement);

        return result.canAccepts;

    }

    /**
     * 判断容器类通用的条件
     * @param data 新控件的类型、所属分类
     * @returns boolean
     */
    canAccept(sourceElement: BuilderHTMLElement, targetElement?: BuilderHTMLElement) {

        const serviceHost = this.options.designerHost;
        const dragResolveService = serviceHost.getService('DragResolveService');
        const resolveContext = dragResolveService.getComponentResolveContext(sourceElement, this) as ComponentResolveContext;

        const targetCmpInstance = targetElement && targetElement.componentInstance;

        const domService = serviceHost.getService('DomService') as DomService;
        const cmp = domService.getComponentById(this.componentId);
        const componentType = cmp.componentType;

        // 实体树拖拽的实体节点，只能放在跟组件
        if (resolveContext.sourceType === 'entity') {
            if (componentType !== FormComponentType.Frame && componentType !== FormComponentType.modalFrame) {
                return { resolveContext, canAccepts: false };
            }
        }

        // 工具箱中需要绑定实体的控件，只能放在根组件中。
        if (resolveContext.sourceType === 'control' && resolveContext.controlCategory === 'dataCollection') {
            if (componentType !== FormComponentType.Frame && componentType !== FormComponentType.modalFrame) {
                return { resolveContext, canAccepts: false };
            }
        }

        // Component 类只能放在根组件中
        if (resolveContext.controlType === DgControl.Component.type) {
            if (componentType !== FormComponentType.Frame && componentType !== FormComponentType.modalFrame) {
                return { resolveContext, canAccepts: false };
            }
            // DataGrid、TreeGrid、ListView的Component组件 只能放在TabPage/Section里
            if (sourceElement.componentInstance) {
                const cmpType = sourceElement.componentInstance.component.componentType || '';
                const restrictCollection = [FormComponentType.dataGrid, FormComponentType.listView, 'ListView'];
                if (restrictCollection.includes(cmpType)) {
                    const parentAllowedDataGrid = [DgControl.Tab.type, DgControl.Section.type, DgControl.Splitter.type, DgControl.ResponseLayoutItem.type];
                    if (!parentAllowedDataGrid.includes(targetCmpInstance.type)) {
                        return { resolveContext, canAccepts: false };
                    }
                }
            }
        }

        // 除布局容器外，不接收输入类控件
        if (resolveContext.controlCategory === 'input' && targetCmpInstance && targetCmpInstance.type !== DgControl.ResponseLayoutItem.type) {
            return { resolveContext, canAccepts: false };

        }
        // 不接收分组FieldSet
        if (resolveContext.controlType === DgControl.FieldSet.type) {
            return { resolveContext, canAccepts: false };
        }

        // DataGrid只能放在TabPage/Section/ResponseLayoutItem里。
        if (resolveContext.controlType === DgControl.DataGrid.type) {

            const parentAllowedDataGrid = [DgControl.Tab.type, DgControl.Section.type, DgControl.Splitter.type, DgControl.ResponseLayoutItem.type];
            // 零代码场景下允许工具箱中的DataGrid放在ContentContainer中，会自动在DataGrid组件父级补充Container-Section两层结构
            if (this.envType === DesignerEnvType.noCode && resolveContext.sourceType === 'control') {
                parentAllowedDataGrid.push(DgControl.ContentContainer.type);
            }
            if (!parentAllowedDataGrid.includes(targetCmpInstance.type)) {
                return { resolveContext, canAccepts: false };
            }

        }
        // TreeGrid、ListView 只能放在TabPage/Section/ResponseLayoutItem里
        if (targetCmpInstance) {
            const targetCmpType = targetCmpInstance.type;
            const restrictCollection = [DgControl.TreeGrid.type, DgControl.ListView.type];

            if (restrictCollection.includes(resolveContext.controlType)) {
                const parentAllowedDataGrid = [DgControl.Tab.type, DgControl.Section.type, DgControl.Splitter.type, DgControl.ResponseLayoutItem.type];
                if (!parentAllowedDataGrid.includes(targetCmpType)) {
                    return { resolveContext, canAccepts: false };
                }
            }

        }
        //  区块容器只能放在带有f-page-main样式的容器里
        if (resolveContext.sourceType === 'control' && resolveContext.controlType === DgControl.ContentContainer.type) {
            if (resolveContext.controlFeature) {
                const feature = JSON.parse(resolveContext.controlFeature);
                if (feature.isLikeCardContainer && !this.checkIfPageMainContentContainer(targetCmpInstance)) {
                    return { resolveContext, canAccepts: false };
                }
            }


        }

        // 标签页区域、分组面板只能放在根组件的ContentContainer中
        if (resolveContext.controlType === DgControl.Tab.type || resolveContext.controlType === DgControl.Section.type) {
            if (componentType !== FormComponentType.Frame && componentType !== FormComponentType.modalFrame) {
                return { resolveContext, canAccepts: false };
            }
            if (![DgControl.ContentContainer.type, DgControl.Splitter.type, DgControl.ResponseLayoutItem.type].includes(targetCmpInstance.type)) {
                return { resolveContext, canAccepts: false };
            }
        }

        // 布局容器只能放在根组件中
        if (resolveContext.controlType === DgControl.ResponseLayout.type) {
            if (componentType !== FormComponentType.Frame && componentType !== FormComponentType.modalFrame) {
                return { resolveContext, canAccepts: false };
            }
        }



        // 工具箱中的模板类控件
        if (resolveContext.controlCategory === 'componentTemplate' && resolveContext.controlTemplate) {
            const controlTemplateCategory = resolveContext.controlTemplate.templateCategory;
            if (controlTemplateCategory === 'input' && targetCmpInstance && targetCmpInstance.type !== DgControl.ResponseLayoutItem.type) {
                return { resolveContext, canAccepts: false };
            }
            if (controlTemplateCategory === 'container') {
                if (componentType !== FormComponentType.Frame && componentType !== FormComponentType.modalFrame) {
                    return { resolveContext, canAccepts: false };
                }
            }


        }

        return { resolveContext, canAccepts: true };

    }

    private checkIfPageMainContentContainer(targetCmpInstance: any) {
        if (!targetCmpInstance || targetCmpInstance.type !== DgControl.ContentContainer.type || !targetCmpInstance.component) {
            return false;
        }
        const cls = targetCmpInstance.component.appearance && targetCmpInstance.component.appearance.class || '';
        if (cls.includes('f-page-main')) {
            return true;
        }
        return false;
    }
}
